Releasing v4.11.0#107
Conversation
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
7b1a491 to
0ef3c51
Compare
WalkthroughThe PR updates JSON serialization for ChangesJSON serialization and release metadata
Sequence Diagram(s)Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/main/java/com/chargebee/v4/internal/JsonUtil.java`:
- Around line 40-41: The Timestamp serializer in JsonUtil is still emitting
epoch milliseconds via the registered TypeAdapter, but the contract now expects
Unix seconds. Update the Timestamp serialization used by the Gson builder in
JsonUtil so it converts the value from src.getTime() to seconds before creating
the JsonPrimitive, and make sure the behavior matches getTimestamp(...) and the
regression tests for expires_at.
- Around line 45-46: The enum JSON serializer in JsonUtil currently lowercases
names using the JVM default locale, which can change wire-format values on
locale-sensitive systems. Update the serializer registered in JsonUtil’s type
hierarchy adapter to use Locale.ROOT when calling toLowerCase so enum
serialization stays stable regardless of default locale.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 3acd0fdb-16e5-4475-a148-af91e86b79a0
📒 Files selected for processing (6)
CHANGELOG.mdVERSIONbuild.gradle.ktssrc/main/java/com/chargebee/v4/internal/JsonUtil.javasrc/test/java/com/chargebee/v4/internal/JsonUtilTest.javasrc/test/java/com/chargebee/v4/models/promotionalGrant/params/PromotionalGrantsParamsJsonTest.java
Replace the hand-rolled `instanceof`-chain inside `toJsonElement(...)` with a single static `Gson` instance configured via `GsonBuilder`: - `Timestamp` → Unix-seconds JSON number (`JsonSerializer<Timestamp>`) - `Date` → `yyyy-MM-dd` JSON string (`JsonSerializer<Date>`) - `Enum` → lowercase `name()` string (`registerTypeHierarchyAdapter`) `toJson(Map)` and `toJson(List)` now delegate to `GSON.toJson(...)`; Gson natively walks nested maps, lists, and `Object[]` and dispatches each value through the registered adapters via its `ObjectTypeAdapter`. The builder also calls `disableHtmlEscaping()` and `serializeNulls()` to preserve the prior behavior (`JsonElement.toString()` semantics and the explicit `"key":null` shape). No behavior change for the Chargebee API contract; the full JsonUtil and PromotionalGrantsParams regression suites pass. Co-authored-by: Cursor <cursoragent@cursor.com>
0ef3c51 to
e8fe429
Compare
There was a problem hiding this comment.
♻️ Duplicate comments (2)
src/main/java/com/chargebee/v4/internal/JsonUtil.java (2)
40-41: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winExisting blocker still applies: serialize
Timestampas Unix seconds.Line 41 emits epoch milliseconds, while the PR objective and the local comment require Unix seconds. This keeps JSON
expires_atvalues 1000x too large; update this serializer and the new millisecond-based test expectations.Proposed fix
.registerTypeAdapter(Timestamp.class, - (JsonSerializer<Timestamp>) (src, t, c) -> new JsonPrimitive(src.getTime())) + (JsonSerializer<Timestamp>) (src, t, c) -> new JsonPrimitive(src.getTime() / 1000L))As per path instructions, this is limited to a merge-blocking correctness issue.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/main/java/com/chargebee/v4/internal/JsonUtil.java` around lines 40 - 41, The Timestamp serializer in JsonUtil currently emits epoch milliseconds via the JsonSerializer registered in JsonUtil, which breaks the expected Unix-seconds format. Update the Timestamp type adapter to divide the timestamp value by 1000 before serializing, and adjust the related tests that currently assert millisecond-based expires_at values so they expect Unix seconds instead.Source: Path instructions
45-46: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winExisting blocker still applies: make enum casing locale-independent.
src.name().toLowerCase()uses the JVM default locale, so API enum values can change on Turkish/default-locale systems. UseLocale.ROOT.Proposed fix
.registerTypeHierarchyAdapter(Enum.class, - (JsonSerializer<Enum<?>>) (src, t, c) -> new JsonPrimitive(src.name().toLowerCase())) + (JsonSerializer<Enum<?>>) (src, t, c) -> new JsonPrimitive(src.name().toLowerCase(java.util.Locale.ROOT)))As per path instructions, this is limited to a merge-blocking correctness issue.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/main/java/com/chargebee/v4/internal/JsonUtil.java` around lines 45 - 46, The enum serialization in JsonUtil’s type hierarchy adapter still depends on the JVM default locale, so update the Enum.class serializer to convert names to lowercase using Locale.ROOT instead of the locale-sensitive default. Keep the change local to the existing JsonUtil registration logic so the JSON output from enum values remains stable across all locales.Source: Path instructions
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Duplicate comments:
In `@src/main/java/com/chargebee/v4/internal/JsonUtil.java`:
- Around line 40-41: The Timestamp serializer in JsonUtil currently emits epoch
milliseconds via the JsonSerializer registered in JsonUtil, which breaks the
expected Unix-seconds format. Update the Timestamp type adapter to divide the
timestamp value by 1000 before serializing, and adjust the related tests that
currently assert millisecond-based expires_at values so they expect Unix seconds
instead.
- Around line 45-46: The enum serialization in JsonUtil’s type hierarchy adapter
still depends on the JVM default locale, so update the Enum.class serializer to
convert names to lowercase using Locale.ROOT instead of the locale-sensitive
default. Keep the change local to the existing JsonUtil registration logic so
the JSON output from enum values remains stable across all locales.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 5b23ee97-b5db-45de-9ac1-13a735e52354
📒 Files selected for processing (3)
src/main/java/com/chargebee/v4/internal/JsonUtil.javasrc/test/java/com/chargebee/v4/internal/JsonUtilTest.javasrc/test/java/com/chargebee/v4/models/promotionalGrant/params/PromotionalGrantsParamsJsonTest.java
- Regenerate param classes with dedicated toJsonMap()/toJsonString() so JSON content-type endpoints emit a proper nested structure instead of reusing the form-url-encoded flattening (e.g. events[...][]) and double-encoding nested objects. - Change usage_timestamp on UsageEvent create and batch ingest from Timestamp to Long (epoch milliseconds) to preserve the precision the ingestion API requires. - Update PromotionalGrantsParamsJsonTest to assert the nested-object JSON body for metadata. - Update CHANGELOG for v4.11.0 (release date and new bug-fix entries). Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/main/java/com/chargebee/v4/models/entitlement/params/EntitlementListParams.java (1)
160-225: 🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy liftDo not swap these public enum type names in a
4.11.0release.Changing
EntityTypeIs/EntityTypeInremoves old nested enum symbols from the published API. Existing consumers compiled against either type will break even though the wire values are unchanged. The same compatibility break also appears insrc/main/java/com/chargebee/v4/models/ramp/params/RampListParams.java.Keep the old enum names, or defer the rename to a major release with compatibility shims. As per path instructions, "Comment only when the issue must be resolved before merge."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/main/java/com/chargebee/v4/models/entitlement/params/EntitlementListParams.java` around lines 160 - 225, The public nested enum names in EntityTypeIn and EntityTypeIs have been swapped, which breaks the existing API surface for consumers compiled against the old symbols. Restore the original enum type names in EntitlementListParams and keep the wire values unchanged; if the rename is still needed, add backward-compatible aliases/shims instead of removing the old nested types. Apply the same compatibility fix in RampListParams so both parameter classes preserve their published enum symbols for this release.Source: Path instructions
src/test/java/com/chargebee/v4/models/promotionalGrant/params/PromotionalGrantsParamsJsonTest.java (1)
36-57: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winFix JSON timestamp expectations to Unix seconds.
The PR objective says JSON
Timestampparams must serialize as numeric Unix seconds, matching the form path, but these tests assertTimestamp.getTime()milliseconds. That either fails against the intended fix or locks in the wrong API contract.🐛 Proposed test fix
- `@DisplayName`("JSON body: expires_at must be Unix-millis number, not human-readable") + `@DisplayName`("JSON body: expires_at must be Unix-seconds number, not human-readable") void jsonBodyEmitsExpiresAtAsUnixMillisNumber() { Timestamp expiresAt = Timestamp.from(Instant.parse("2026-06-23T09:54:44Z")); - long expectedUnixMillis = expiresAt.getTime(); + long expectedUnixSeconds = expiresAt.getTime() / 1000L; ... - assertEquals(expectedUnixMillis, JsonUtil.getLong(parsed, "expires_at"), - "expires_at must be Unix millis (number) in the JSON body"); + assertEquals(expectedUnixSeconds, JsonUtil.getLong(parsed, "expires_at"), + "expires_at must be Unix seconds (number) in the JSON body"); ... Timestamp expiresAt = Timestamp.from(Instant.now().plus(1, ChronoUnit.DAYS)); - long expectedUnixMillis = expiresAt.getTime(); + long expectedUnixSeconds = expiresAt.getTime() / 1000L; ... - assertEquals(expectedUnixMillis, JsonUtil.getLong(parsed, "expires_at")); + assertEquals(expectedUnixSeconds, JsonUtil.getLong(parsed, "expires_at")); ... - assertEquals(expiresAt.getTime(), JsonUtil.getLong(parsed, "expires_at")); + assertEquals(expiresAt.getTime() / 1000L, JsonUtil.getLong(parsed, "expires_at"));Also applies to: 67-80, 102-105
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/test/java/com/chargebee/v4/models/promotionalGrant/params/PromotionalGrantsParamsJsonTest.java` around lines 36 - 57, The JSON timestamp assertions in PromotionalGrantsParamsJsonTest are locking in Unix-millis behavior instead of the intended Unix-seconds contract. Update the expectations in jsonBodyEmitsExpiresAtAsUnixMillisNumber and the related JSON timestamp tests to assert numeric Unix seconds rather than Timestamp.getTime() milliseconds, using the same JSON field checks around PromotionalGrantsParams.toJsonString and JsonUtil. Keep the test focused on verifying that expiresAt serializes as a number in seconds for the JSON body.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@src/main/java/com/chargebee/v4/models/promotionalGrant/params/PromotionalGrantsParams.java`:
- Around line 93-135: The JSON timestamp contract for PromotionalGrantsParams is
inconsistent: toJsonMap() currently passes expiresAt through as a raw Timestamp,
while the PR expectation and regression should agree on Unix seconds rather than
milliseconds. Update the PromotionalGrantsParams.toJsonMap()/toJsonString path
so expires_at is serialized in the intended unit, and make the associated
regression/test assertion match that same contract using the unique expiresAt
and JsonUtil serialization flow.
In
`@src/main/java/com/chargebee/v4/models/usageEvent/params/UsageEventBatchIngestParams.java`:
- Line 112: Restore Timestamp-compatible APIs in UsageEventBatchIngestParams,
EventsParams, and EventsBuilder by keeping the internal numeric usageTimestamp
representation but adding deprecated Timestamp overloads/accessors for existing
callers. Update the relevant getter and builder methods named getUsageTimestamp
and usageTimestamp(...) to preserve backward compatibility while still
supporting the new wire format.
---
Outside diff comments:
In
`@src/main/java/com/chargebee/v4/models/entitlement/params/EntitlementListParams.java`:
- Around line 160-225: The public nested enum names in EntityTypeIn and
EntityTypeIs have been swapped, which breaks the existing API surface for
consumers compiled against the old symbols. Restore the original enum type names
in EntitlementListParams and keep the wire values unchanged; if the rename is
still needed, add backward-compatible aliases/shims instead of removing the old
nested types. Apply the same compatibility fix in RampListParams so both
parameter classes preserve their published enum symbols for this release.
In
`@src/test/java/com/chargebee/v4/models/promotionalGrant/params/PromotionalGrantsParamsJsonTest.java`:
- Around line 36-57: The JSON timestamp assertions in
PromotionalGrantsParamsJsonTest are locking in Unix-millis behavior instead of
the intended Unix-seconds contract. Update the expectations in
jsonBodyEmitsExpiresAtAsUnixMillisNumber and the related JSON timestamp tests to
assert numeric Unix seconds rather than Timestamp.getTime() milliseconds, using
the same JSON field checks around PromotionalGrantsParams.toJsonString and
JsonUtil. Keep the test focused on verifying that expiresAt serializes as a
number in seconds for the JSON body.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Enterprise
Run ID: ced4388a-0fdb-4bf3-88cf-eaf769d34781
📒 Files selected for processing (16)
CHANGELOG.mdsrc/main/java/com/chargebee/v4/models/entitlement/params/EntitlementListParams.javasrc/main/java/com/chargebee/v4/models/ledgerOperation/params/LedgerOperationAuthorizeParams.javasrc/main/java/com/chargebee/v4/models/ledgerOperation/params/LedgerOperationCaptureAuthorizationParams.javasrc/main/java/com/chargebee/v4/models/ledgerOperation/params/LedgerOperationCaptureParams.javasrc/main/java/com/chargebee/v4/models/ledgerOperation/params/LedgerOperationReleaseAuthorizationParams.javasrc/main/java/com/chargebee/v4/models/ledgerOperation/params/ListLedgerOperationsParams.javasrc/main/java/com/chargebee/v4/models/offerEvent/params/OfferEventsParams.javasrc/main/java/com/chargebee/v4/models/offerFulfillment/params/OfferFulfillmentsParams.javasrc/main/java/com/chargebee/v4/models/offerFulfillment/params/OfferFulfillmentsUpdateParams.javasrc/main/java/com/chargebee/v4/models/personalizedOffer/params/PersonalizedOffersParams.javasrc/main/java/com/chargebee/v4/models/promotionalGrant/params/PromotionalGrantsParams.javasrc/main/java/com/chargebee/v4/models/ramp/params/RampListParams.javasrc/main/java/com/chargebee/v4/models/usageEvent/params/UsageEventBatchIngestParams.javasrc/main/java/com/chargebee/v4/models/usageEvent/params/UsageEventCreateParams.javasrc/test/java/com/chargebee/v4/models/promotionalGrant/params/PromotionalGrantsParamsJsonTest.java
✅ Files skipped from review due to trivial changes (1)
- CHANGELOG.md
v4.11.0 (2026-06-23)
Bug Fixes:
Timestampparameters were sent in a human-readable format (e.g."expires_at":"2026-06-23 09:54:44.513") instead of Unix seconds. They are now serialized as numeric Unix seconds (e.g."expires_at":1782189229), matching the form-url-encoded path and the format expected by the API. This affects all JSON content-type endpoints, such ascreate_promotional_grantinPromotionalGrant.Released v4.11.0 with a JSON request-body serialization fix:
Timestampfields inapplication/jsonnow serialize as numeric Unix seconds (not human-readable strings). Regenerated parameter classes addtoJsonMap()to preserve nested JSON structures (fixing flattening/double-encoding). UpdatedPromotionalGrantandUsageEvent(usage_timestampnowLong), plus new tests and changelog.